﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using TowerDef_s_enseLibrary.map;
using TowerDef_s_enseLibrary.enemy;
using TowerDef_s_enseLibrary.player;

namespace TowerDef_s_enseLibrary.game
{
    public class Wave
    {
        #region variables

        private int _numOfEnemies; // Number of _enemies to spawn
        private int _enemiesSpawned = 0; // How mant _enemies have spawned
        private int _waveNumber; // What wave is this?

        private float _spawnTimer = 0; // When should we spawn an enemy

        private bool _enemyAtEnd; // Has an enemy reached the end of the path?
        private bool _spawningEnemies; // Are we still spawing _enemies?

        private Map _map; // A reference of the _map

        private Texture2D _enemyTexture; // A Texture for the _enemies
        private Texture2D _healthTexture; // A Texture for the health bar.

        private List<Enemy> _enemies = new List<Enemy>(); // List of _enemies

        private Player _player; // A reference to the _player.

        /// <summary>
        /// Get true if all _enemies are death or oon target
        /// </summary>
        public bool RoundOver
        {
            get
            {
                return _enemies.Count == 0 && _enemiesSpawned == _numOfEnemies;
            }
        }

        /// <summary>
        /// Get the round number
        /// </summary>
        public int RoundNumber
        {
            get { return _waveNumber; }
        }

        /// <summary>
        /// Get and set the state of the enemy
        /// </summary>
        public bool EnemyAtEnd
        {
            get { return _enemyAtEnd; }
            set { _enemyAtEnd = value; }
        }

        /// <summary>
        /// Get the enemie list
        /// </summary>
        public List<Enemy> Enemies
        {
            get { return _enemies; }
        }

        #endregion variables

        #region functions

        /// <summary>
        /// Creates a new wave
        /// </summary>
        /// <param name="waveNumber">The number of the wave</param>
        /// <param name="numOfEnemies">The number of _enemies</param>
        /// <param name="player">The playing _player</param>
        /// <param name="map">The map</param>
        /// <param name="enemyTexture">The Texture fpr the _enemies</param>
        /// <param name="healthTexture">The healthbar Texture</param>
        public Wave(int waveNumber, int numOfEnemies, Player player, Map map, Texture2D enemyTexture, Texture2D healthTexture)
        {
            this._waveNumber = waveNumber;
            this._numOfEnemies = numOfEnemies;

            this._player = player;
            this._map = map;

            this._enemyTexture = enemyTexture;
            // Initialze our new Texture field
            this._healthTexture = healthTexture;
        }

        /// <summary>
        /// Add a enemy
        /// </summary>
        private void AddEnemy()
        {
            var enemy = new Enemy(_enemyTexture,
            _map.Waypoints.Peek(), 50, 1, 0.5f);
            enemy.SetWaypoints(_map.Waypoints);
            _enemies.Add(enemy);
            _spawnTimer = 0;
            _enemiesSpawned++;

            if (_waveNumber == 5)
            {
                float speed = 2.0f;
                enemy = new Enemy(_enemyTexture, _map.Waypoints.Peek(), 50, 1, speed);
                enemy.SetWaypoints(_map.Waypoints);
                _spawnTimer = 0;
                _enemiesSpawned++;
            }
        }

        /// <summary>
        /// Set the start of a wave
        /// </summary>
        public void Start()
        {
            _spawningEnemies = true;
        }

        /// <summary>
        /// Updates the wave
        /// </summary>
        /// <param name="gameTime">The current game time</param>
        public void Update(GameTime gameTime)
        {
            if (_enemiesSpawned == _numOfEnemies)
                _spawningEnemies = false; // We have spawned enough _enemies

            if (_spawningEnemies)
            {
                _spawnTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
                if (_spawnTimer > 2)
                    AddEnemy(); // Time to add a new enemey
            }

            for (int i = 0; i < _enemies.Count; i++)
            {
                Enemy enemy = _enemies[i];
                enemy.Update(gameTime);
                if(enemy.IsDead)
                {
                    if(enemy.CurrentHealth > 0) // Enemy is at the end
                    {
                        _enemyAtEnd = true;
                        _player.Lives -= 1;
                    }

                    else
                    {
                        _player.Money += enemy.BountyGiven;
                    }

                    _enemies.Remove(enemy);
                    i--;
                }
            }
        }

        /// <summary>
        /// Draws the current wave textures
        /// </summary>
        /// <param name="spriteBatch">A group of sprite settings</param>
        public void Draw(SpriteBatch spriteBatch)
        {
            foreach(Enemy enemy in _enemies)
            {
                enemy.Draw(spriteBatch);

                // Draw the health bar normally.
                var healthRectangle = new Rectangle((int)enemy.Position.X, (int)enemy.Position.Y, _healthTexture.Width, _healthTexture.Height);

                spriteBatch.Draw(_healthTexture, healthRectangle, Color.Gray);

                float healthPercentage = enemy.HealthPercentage;
                float visibleWidth = (float)_healthTexture.Width * healthPercentage;

                healthRectangle = new Rectangle((int)enemy.Position.X, (int)enemy.Position.Y, (int)(visibleWidth), _healthTexture.Height);

                float red = (healthPercentage < 0.5 ? 1 : 1 - (2 * healthPercentage - 1));
                float green = (healthPercentage > 0.5 ? 1 : (2 * healthPercentage));
                var healthColor = new Color(red, green, 0);
                spriteBatch.Draw(_healthTexture, healthRectangle, healthColor);

                spriteBatch.Draw(_healthTexture, healthRectangle, Color.Gold);
            }
        }

        #endregion functions

        #region events



        #endregion events
    }
}
